// 引入必要的命名空间
using System.Text.Json; // 引入JSON序列化工具
using UniversalAdmin.Application.DTOs; // 引入数据传输对象定义
using UniversalAdmin.Domain.Entities; // 引入领域实体定义
using UniversalAdmin.Domain.Repositories; // 引入仓储接口定义

// 定义服务层的命名空间
namespace UniversalAdmin.Application.Services;

// 实现系统配置服务接口
public class SystemConfigService : ISystemConfigService
{
    // 注入系统配置仓储接口
    private readonly ISystemConfigRepository _configRepository;

    // 构造函数，依赖注入系统配置仓储接口
    public SystemConfigService(ISystemConfigRepository configRepository)
    {
        _configRepository = configRepository;
    }

    // 获取所有系统配置
    public async Task<IEnumerable<SystemConfigDto>> GetAllConfigsAsync()
    {
        // 调用仓储层获取所有配置
        var configs = await _configRepository.GetAllAsync();
        // 将配置实体映射为DTO并返回
        return configs.Select(MapToDto);
    }

    // 根据键获取单个系统配置
    public async Task<SystemConfigDto?> GetConfigByKeyAsync(string key)
    {
        // 调用仓储层根据键获取配置
        var config = await _configRepository.GetByKeyAsync(key);
        // 如果配置存在，映射为DTO并返回；否则返回null
        return config != null ? MapToDto(config) : null;
    }

    // 创建新系统配置
    public async Task<SystemConfigDto> CreateConfigAsync(CreateSystemConfigDto dto)
    {
        // 根据DTO创建配置实体
        var config = new SystemConfig
        {
            Key = dto.Key,
            Value = dto.Value,
            Description = dto.Description,
            CreatedAt = DateTime.UtcNow
        };

        // 调用仓储层添加配置
        var createdConfig = await _configRepository.AddAsync(config);
        // 将新创建的配置映射为DTO并返回
        return MapToDto(createdConfig);
    }

    // 更新系统配置
    public async Task<SystemConfigDto?> UpdateConfigAsync(string key, UpdateSystemConfigDto dto)
    {
        // 调用仓储层根据键获取配置
        var config = await _configRepository.GetByKeyAsync(key);
        // 如果配置不存在，返回null
        if (config == null) return null;

        // 更新配置属性
        config.Value = dto.Value;
        config.Description = dto.Description;
        config.UpdatedAt = DateTime.UtcNow;

        // 调用仓储层更新配置
        await _configRepository.UpdateAsync(config);
        // 将更新后的配置映射为DTO并返回
        return MapToDto(config);
    }

    // 删除系统配置
    public async Task<bool> DeleteConfigAsync(string key)
    {
        // 调用仓储层根据键获取配置
        var config = await _configRepository.GetByKeyAsync(key);
        // 如果配置不存在，返回false
        if (config == null) return false;

        // 调用仓储层删除配置
        await _configRepository.DeleteAsync(key);
        // 返回删除成功标志
        return true;
    }

    // 获取系统配置值（泛型方法）
    public async Task<T?> GetConfigValueAsync<T>(string key, T? defaultValue = default)
    {
        // 调用仓储层根据键获取配置
        var config = await _configRepository.GetByKeyAsync(key);
        // 如果配置不存在，返回默认值
        if (config == null) return defaultValue;

        try
        {
            // 尝试将配置值反序列化为指定类型
            return JsonSerializer.Deserialize<T>(config.Value);
        }
        catch
        {
            // 反序列化失败时返回默认值
            return defaultValue;
        }
    }

    // 设置系统配置值（泛型方法）
    public async Task SetConfigValueAsync<T>(string key, T value, string? description = null)
    {
        // 调用仓储层根据键获取配置
        var config = await _configRepository.GetByKeyAsync(key);
        // 将值序列化为JSON字符串
        var jsonValue = JsonSerializer.Serialize(value);

        if (config == null)
        {
            // 创建新配置
            config = new SystemConfig
            {
                Key = key,
                Value = jsonValue,
                Description = description,
                CreatedAt = DateTime.UtcNow
            };
            await _configRepository.AddAsync(config);
        }
        else
        {
            // 更新现有配置
            config.Value = jsonValue;
            if (description != null)
                config.Description = description;
            config.UpdatedAt = DateTime.UtcNow;
            await _configRepository.UpdateAsync(config);
        }
    }

    // 将系统配置实体映射为DTO
    private static SystemConfigDto MapToDto(SystemConfig config)
    {
        return new SystemConfigDto
        {
            Key = config.Key,
            Value = config.Value,
            Description = config.Description,
            CreatedAt = config.CreatedAt,
            UpdatedAt = config.UpdatedAt
        };
    }
}